package com.bookrecomm.service.impl;

import com.bookrecomm.dao.BookRepository;
import com.bookrecomm.dao.CategoryRepository;
import com.bookrecomm.dao.ReadHistoryRepository;
import org.springframework.data.domain.PageRequest;
import com.bookrecomm.dao.TagRepository;
import com.bookrecomm.entity.Book;
import com.bookrecomm.entity.Category;
import com.bookrecomm.entity.ReadHistory;
import com.bookrecomm.entity.Tag;
import com.bookrecomm.service.BookService;
import com.bookrecomm.vo.BookVO;
import com.bookrecomm.vo.CategoryVO;
import com.bookrecomm.vo.PageVO;
import com.bookrecomm.vo.TagVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 图书服务实现类
 * 实现图书相关的业务逻辑
 */
@Service("bookService")
public class BookServiceImpl implements BookService {

    @Autowired
    private BookRepository bookRepository;

    @Autowired
    private CategoryRepository categoryRepository;

    @Autowired
    private TagRepository tagRepository;

    @Autowired
    private ReadHistoryRepository readHistoryRepository;

    /**
     * 根据ID查询图书
     * @param id 图书ID
     * @return 图书信息
     */
    @Override
    public BookVO findById(Long id) {
        Book book = bookRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("图书不存在"));
        return convertToBookVO(book);
    }

    /**
     * 分页查询图书列表
     * @param pageable 分页参数
     * @return 分页图书列表
     */
    @Override
    public PageVO<BookVO> findAll(Pageable pageable) {
        Page<Book> bookPage = bookRepository.findAll(pageable);
        return convertToPageVO(bookPage);
    }

    /**
     * 根据分类ID查询图书列表
     * @param categoryId 分类ID
     * @param pageable 分页参数
     * @return 分页图书列表
     */
    @Override
    public PageVO<BookVO> findByCategoryId(Long categoryId, Pageable pageable) {
        // 查询分类
        Category category = categoryRepository.findById(categoryId)
                .orElseThrow(() -> new RuntimeException("分类不存在"));
        
        // 查询图书
        Page<Book> bookPage = bookRepository.findByCategoryId(categoryId, pageable);
        return convertToPageVO(bookPage);
    }

    /**
     * 根据标签ID查询图书列表
     * @param tagId 标签ID
     * @param pageable 分页参数
     * @return 分页图书列表
     */
    @Override
    public PageVO<BookVO> findByTagId(Long tagId, Pageable pageable) {
        // 查询标签
        Tag tag = tagRepository.findById(tagId)
                .orElseThrow(() -> new RuntimeException("标签不存在"));
        
        // 查询图书
        Page<Book> bookPage = bookRepository.findByTagId(tagId, pageable);
        return convertToPageVO(bookPage);
    }

    /**
     * 搜索图书
     * @param keyword 关键词
     * @param pageable 分页参数
     * @return 分页图书列表
     */
    @Override
    public PageVO<BookVO> search(String keyword, Pageable pageable) {
        Page<Book> bookPage = bookRepository.searchBooks(keyword, pageable);
        return convertToPageVO(bookPage);
    }

    /**
     * 获取推荐图书列表
     * @param userId 用户ID，可为null表示未登录用户
     * @param limit 限制数量
     * @return 推荐图书列表
     */
    @Override
    public List<BookVO> getRecommendations(Long userId, int limit) {
        List<Book> books;
        
        // 如果用户已登录，根据用户阅读历史推荐
        if (userId != null) {
            // 获取用户最近阅读的图书的分类和标签
            List<ReadHistory> readHistories = readHistoryRepository.findRecentReadByUserId(userId, PageRequest.of(0, 10));
            if (!readHistories.isEmpty()) {
                // 提取分类和标签ID
                List<Long> categoryIds = new ArrayList<>();
                List<Long> tagIds = new ArrayList<>();
                
                for (ReadHistory history : readHistories) {
                    Book book = history.getBook();
                    if (book != null) {
                        // 添加分类ID
                        if (book.getCategories() != null) {
                            book.getCategories().forEach(category -> categoryIds.add(category.getId()));
                        }
                        
                        // 添加标签ID
                        if (book.getTags() != null) {
                            book.getTags().forEach(tag -> tagIds.add(tag.getId()));
                        }
                    }
                }
                
                // 根据分类和标签推荐图书
                if (!categoryIds.isEmpty() || !tagIds.isEmpty()) {
                    books = bookRepository.findRecommendedBooks(categoryIds, tagIds, limit);
                    
                    // 如果推荐图书不足，补充热门图书
                    if (books.size() < limit) {
                        List<Book> hotBooks = bookRepository.findTop10ByOrderBySalesDesc();
                        for (Book book : hotBooks) {
                            if (books.size() >= limit) {
                                break;
                            }
                            if (!books.contains(book)) {
                                books.add(book);
                            }
                        }
                    }
                    
                    return books.stream().map(this::convertToBookVO).collect(Collectors.toList());
                }
            }
        }
        
        // 默认返回热门图书
        books = bookRepository.findTop10ByOrderBySalesDesc();
        return books.stream().limit(limit).map(this::convertToBookVO).collect(Collectors.toList());
    }

    /**
     * 获取热门图书列表
     * @param limit 限制数量
     * @return 热门图书列表
     */
    @Override
    public List<BookVO> getHotBooks(int limit) {
        List<Book> books = bookRepository.findTop10ByOrderBySalesDesc();
        return books.stream().limit(limit).map(this::convertToBookVO).collect(Collectors.toList());
    }

    /**
     * 获取新书列表
     * @param limit 限制数量
     * @return 新书列表
     */
    @Override
    public List<BookVO> getNewBooks(int limit) {
        List<Book> books = bookRepository.findTop10ByOrderByCreatedAtDesc();
        return books.stream().limit(limit).map(this::convertToBookVO).collect(Collectors.toList());
    }

    /**
     * 添加图书
     * @param book 图书信息
     * @return 添加后的图书信息
     */
    @Override
    @Transactional
    public BookVO addBook(Book book) {
        // 设置创建时间和更新时间
        book.setCreatedAt(LocalDateTime.now());
        book.setUpdatedAt(LocalDateTime.now());
        
        // 保存图书
        Book savedBook = bookRepository.save(book);
        
        return convertToBookVO(savedBook);
    }

    /**
     * 更新图书信息
     * @param id 图书ID
     * @param bookUpdate 图书信息
     * @return 更新后的图书信息
     */
    @Override
    @Transactional
    public BookVO updateBook(Long id, Book bookUpdate) {
        Book book = bookRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("图书不存在"));
        
        // 更新图书信息
        if (bookUpdate.getTitle() != null) {
            book.setTitle(bookUpdate.getTitle());
        }
        if (bookUpdate.getIsbn() != null) {
            book.setIsbn(bookUpdate.getIsbn());
        }
        if (bookUpdate.getAuthor() != null) {
            book.setAuthor(bookUpdate.getAuthor());
        }
        if (bookUpdate.getPublisher() != null) {
            book.setPublisher(bookUpdate.getPublisher());
        }
        if (bookUpdate.getPublishDate() != null) {
            book.setPublishDate(bookUpdate.getPublishDate());
        }
        if (bookUpdate.getLanguage() != null) {
            book.setLanguage(bookUpdate.getLanguage());
        }
        if (bookUpdate.getPrice() != null) {
            book.setPrice(bookUpdate.getPrice());
        }
        if (bookUpdate.getPages() != null) {
            book.setPages(bookUpdate.getPages());
        }
        if (bookUpdate.getCoverUrl() != null) {
            book.setCoverUrl(bookUpdate.getCoverUrl());
        }
        if (bookUpdate.getDescription() != null) {
            book.setDescription(bookUpdate.getDescription());
        }
        if (bookUpdate.getCatalog() != null) {
            book.setCatalog(bookUpdate.getCatalog());
        }
        if (bookUpdate.getSales() != null) {
            book.setSales(bookUpdate.getSales());
        }
        if (bookUpdate.getStock() != null) {
            book.setStock(bookUpdate.getStock());
        }
        if (bookUpdate.getStatus() != null) {
            book.setStatus(bookUpdate.getStatus());
        }
        
        // 更新分类和标签
        if (bookUpdate.getCategories() != null) {
            book.setCategories(bookUpdate.getCategories());
        }
        if (bookUpdate.getTags() != null) {
            book.setTags(bookUpdate.getTags());
        }
        
        // 更新时间
        book.setUpdatedAt(LocalDateTime.now());
        
        // 保存图书
        Book savedBook = bookRepository.save(book);
        
        return convertToBookVO(savedBook);
    }

    /**
     * 删除图书
     * @param id 图书ID
     * @return 是否删除成功
     */
    @Override
    @Transactional
    public boolean deleteBook(Long id) {
        if (!bookRepository.existsById(id)) {
            throw new RuntimeException("图书不存在");
        }
        
        bookRepository.deleteById(id);
        return true;
    }

    /**
     * 更新图书状态
     * @param id 图书ID
     * @param status 状态：0-下架，1-上架
     * @return 是否更新成功
     */
    @Override
    @Transactional
    public boolean updateStatus(Long id, Integer status) {
        Book book = bookRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("图书不存在"));
        
        book.setStatus(status);
        book.setUpdatedAt(LocalDateTime.now());
        bookRepository.save(book);
        
        return true;
    }

    /**
     * 将图书实体转换为VO对象，并根据用户ID设置是否收藏和阅读进度
     * @param book 图书实体
     * @param userId 用户ID
     * @return 图书VO对象
     */
    @Override
    public BookVO convertToBookVO(Book book, Long userId) {
        BookVO bookVO = new BookVO();
        BeanUtils.copyProperties(book, bookVO);
        
        // 设置分类
        if (book.getCategories() != null) {
            List<CategoryVO> categoryVOs = book.getCategories().stream().map(category -> {
                CategoryVO categoryVO = new CategoryVO();
                BeanUtils.copyProperties(category, categoryVO);
                return categoryVO;
            }).collect(Collectors.toList());
            bookVO.setCategories(categoryVOs);
        }
        
        // 设置标签
        if (book.getTags() != null) {
            List<TagVO> tagVOs = book.getTags().stream().map(tag -> {
                TagVO tagVO = new TagVO();
                BeanUtils.copyProperties(tag, tagVO);
                return tagVO;
            }).collect(Collectors.toList());
            bookVO.setTags(tagVOs);
        }
        
        // 设置统计数据
        bookVO.setCommentCount(book.getComments() != null ? (long) book.getComments().size() : 0L);
        bookVO.setFavoriteCount(book.getFavorites() != null ? book.getFavorites().size() : 0);
        bookVO.setReaderCount(book.getReadHistories() != null ? 
                book.getReadHistories().stream().map(ReadHistory::getUser).distinct().count() : 0L);
        
        // 设置当前用户是否已收藏和阅读进度
        if (userId != null) {
            // 检查是否已收藏
            bookVO.setFavorited(book.getFavorites() != null && 
                    book.getFavorites().stream().anyMatch(favorite -> 
                            favorite.getUser() != null && 
                            favorite.getUser().getId().equals(userId)));
            
            // 获取阅读进度
            if (book.getReadHistories() != null) {
                Optional<ReadHistory> readHistory = book.getReadHistories().stream()
                        .filter(history -> history.getUser() != null && 
                                history.getUser().getId().equals(userId))
                        .findFirst();
                
                readHistory.ifPresent(history -> bookVO.setReadProgress(history.getProgress()));
            }
        } else {
            bookVO.setFavorited(false);
            bookVO.setReadProgress(0);
        }
        
        return bookVO;
    }
    
    /**
     * 将图书实体转换为VO对象
     * @param book 图书实体
     * @return 图书VO对象
     */
    private BookVO convertToBookVO(Book book) {
        BookVO bookVO = new BookVO();
        BeanUtils.copyProperties(book, bookVO);
        
        // 设置分类
        if (book.getCategories() != null) {
            List<CategoryVO> categoryVOs = book.getCategories().stream().map(category -> {
                CategoryVO categoryVO = new CategoryVO();
                BeanUtils.copyProperties(category, categoryVO);
                return categoryVO;
            }).collect(Collectors.toList());
            bookVO.setCategories(categoryVOs);
        }
        
        // 设置标签
        if (book.getTags() != null) {
            List<TagVO> tagVOs = book.getTags().stream().map(tag -> {
                TagVO tagVO = new TagVO();
                BeanUtils.copyProperties(tag, tagVO);
                return tagVO;
            }).collect(Collectors.toList());
            bookVO.setTags(tagVOs);
        }
        
        // 设置统计数据
        bookVO.setCommentCount(book.getComments() != null ? (long) book.getComments().size() : 0L);
        bookVO.setFavoriteCount(book.getFavorites() != null ? book.getFavorites().size() : 0);
        bookVO.setReaderCount(book.getReadHistories() != null ? 
                book.getReadHistories().stream().map(ReadHistory::getUser).distinct().count() : 0L);
        
        // 设置当前用户是否已收藏和阅读进度
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated() && !"anonymousUser".equals(authentication.getPrincipal())) {
            String username = authentication.getName();
            
            // 检查是否已收藏
            bookVO.setFavorited(book.getFavorites() != null && 
                    book.getFavorites().stream().anyMatch(favorite -> 
                            favorite.getUser() != null && 
                            favorite.getUser().getUsername().equals(username)));
            
            // 获取阅读进度
            if (book.getReadHistories() != null) {
                Optional<ReadHistory> readHistory = book.getReadHistories().stream()
                        .filter(history -> history.getUser() != null && 
                                history.getUser().getUsername().equals(username))
                        .findFirst();
                
                readHistory.ifPresent(history -> bookVO.setReadProgress(history.getProgress()));
            }
        } else {
            bookVO.setFavorited(false);
            bookVO.setReadProgress(0);
        }
        
        return bookVO;
    }

    /**
     * 将图书分页结果转换为分页VO对象
     * @param bookPage 图书分页结果
     * @return 分页VO对象
     */
    private PageVO<BookVO> convertToPageVO(Page<Book> bookPage) {
        List<BookVO> bookVOs = bookPage.getContent().stream()
                .map(this::convertToBookVO)
                .collect(Collectors.toList());
        
        PageVO<BookVO> pageVO = new PageVO<>();
        pageVO.setPageNum(bookPage.getNumber() + 1);
        pageVO.setPageSize(bookPage.getSize());
        pageVO.setTotal(bookPage.getTotalElements());
        pageVO.setPages(bookPage.getTotalPages());
        pageVO.setHasPrevious(bookPage.hasPrevious());
        pageVO.setHasNext(bookPage.hasNext());
        pageVO.setList(bookVOs);
        
        return pageVO;
    }
}
